# -*- coding: utf-8 -*-
"""
Tencent is pleased to support the open source community by making 蓝鲸智云PaaS平台社区版 (BlueKing PaaS Community
Edition) available.
Copyright (C) 2017-2021 THL A29 Limited, a Tencent company. All rights reserved.
Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://opensource.org/licenses/MIT
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
specific language governing permissions and limitations under the License.
"""

import logging

from django.conf import settings
from django.contrib import auth
from django.core.cache import caches

from blueapps.account.conf import ConfFixture
from blueapps.account.handlers.response import ResponseHandler
from blueapps.utils import client

try:
    from django.utils.deprecation import MiddlewareMixin
except Exception:  # pylint: disable=broad-except
    MiddlewareMixin = object


logger = logging.getLogger("component")
cache = caches["login_db"]


class SopsJwtLoginRequiredMiddleware(MiddlewareMixin):
    def process_view(self, request, view, args, kwargs):
        """
        Login by two ways
        1. request_provider拦截http header和在request对象上标记is_wechat... is_sops_jwt
        2. 在setting中是否有对应的middleware,在当前middeware中排除request标记,放行的返回return none
        2. User has logged in calling auth.login
        """
        if hasattr(request, "is_wechat") and request.is_wechat():
            return None

        if hasattr(request, "is_bk_jwt") and request.is_bk_jwt():
            return None

        if hasattr(request, "is_rio") and request.is_rio():
            return None

        if getattr(view, "login_exempt", False):
            return None

        login_exempt = getattr(view, "login_exempt", False)

        if login_exempt or request.user.is_authenticated:
            return None

        # 不被拦截:request中没有is_sops_jwt属性或 is_sops_jwt为否
        # 框架前置中间件，已将识别的客户端信息填充进 request
        if not hasattr(request, "is_sops_jwt") or not request.is_sops_jwt():
            return None

        user = self.authenticate_sops_jwt(request)
        if user:
            return None

        handler = ResponseHandler(ConfFixture, settings)
        return handler.build_sops_jwt_401_response(request)


    def process_response(self, request, response):
        return response

    def authenticate_sops_jwt(self, request):

        # 调用对应的backends
        user = auth.authenticate(request=request)

        # user存在说明token通过并获取db里的User记录, 同时request不存在user（django固定做法通常为判定是否login）
        if user and user.username != request.user.username:
            # 给django auth执行login动作,框架会进行一些动作,如 request填充User数据、is_auth、session等
            auth.login(request, user)
        if request.user.is_authenticated:
            # 登录成功，确认登陆正常后退出
            return request.user
        return user

